package eol

import (
	data2 "api_online/data"
	"encoding/xml"
	"fmt"
	"strings"
)

var dataEol document

const apiTypeService = "服务"

const apiProtocolHttp = "HTTP"

const apiStatusNormal = 1
const apiStatusDisable = 2

const apiDefaultVersion = "1.0.0"

const paramYes = "是"
const paramNo = "否"

const configCacheTypeFile = "File"
const configCacheTypeRedis = "Redis"

const configDefaultCacheTime = 3600
const configDefaultNum = 20

const paramTypeString = "string"

// 整体数据
type document struct {
	Item []item `xml:"item"`
}

// 代表了一个接口
type item struct {
	Api api 	`xml:"api"`		// 接口基本信息
	Config config 	`xml:"config"`	// 接口配置
	Header header 	`xml:"header"`	// 请求头
	Request request `xml:"request"`	// 请求参数
	Response response `xml:"response"`	// 响应参数
}

// 接口基本信息
type api struct {
	Domain	string 	`xml:"domain"`	// 服务器地址
	Type	string 	`xml:"type"`	// 请求接口类型:服务(动态接口);文档(静态文件)
	Name 	string 	`xml:"name"`	// 接口名称
	Uri 	string 	`xml:"uri"`		// 接口短路由(article/info)
	Protocol string `xml:"protocol"`// 协议,可选值: http/https
	Method 	string 	`xml:"method"`	// 请求方法: GET/POST
	Version string 	`xml:"version"`	// 版本
	Status 	int 	`xml:"status"`	// 状态: 1(正常);2(禁用)
	Success string	`xml:"success"`	// 成功数据样本
	Error 	string	`xml:"error"`	// 失败数据样本
	Remark 	string	`xml:"remark"`	// 备注
	Url 	string	`xml:"url"`		// url
}

// 配置信息
type config struct {
	IsAuth	string	`xml:"is_auth"`	// 是否认证.是/否
	IsAdmin	string	`xml:"is_admin"` 	// 是否仅内部访问.是/否
	IsCors	string 	`xml:"is_cors"`	// 是否允许跨域.是/否
	IsCache string	`xml:"is_cache"`// 是否允许缓存.是/否
	CacheType	string	`xml:"cache_type"`	// 缓存方式.File/Redis
	CacheTime	int	`xml:"cache_time"`	// 缓存时间,单位秒
	Num 	int 	`xml:"num"`		// 最大并发数
	IpWhite	string 	`xml:"ip_white"`// ip白名单
	IpBlack	string 	`xml:"ip_black"`// ip黑名单
	IsEncrypt	string	`xml:"is_encrypt"`	// 是否加密.是/否
	Encrypt	string	`xml:"encrypt"` 	// 加密字符串
}

// 接口header头
type header struct {}

// 接口请求参数
type request struct {
	Item []requestItem `xml:"item"`
}

// 返回值
type response struct {}

// 具体请求参数
type requestItem struct {
	Id	int		`xml:"id"`		// 参数ID
	ApiId	int	`xml:"api_id"`	// 接口ID
	RootId	int	`xml:"root_id"`	// 含义未知
	Param 	string	`xml:"param"`	// 参数key
	Content	string	`xml:"content"`	// 参数描述
	ParamType	string	`xml:"param_type"`	// 参数类型. string json int folat double date  datetime boolean byte array long
	Example interface{}	`xml:"example"`	// 参数样例
	IsMust	string 	`xml:"is_must"`		// 是否必填.是/否
	IsRepeat	string	`xml:"is_repeat"`	// 含义未知
	IsCross	string	`xml:"is_cross"` 	// 缓存穿透.是/否
}

func init() {
	dataEol = document{}
}

func Eol(domain string) string {
	cache := data2.Cache

	// 获取文件
	fileList := cache.GetSyntaxFileList()

	for _, v := range fileList {
		descPrefix := v.Desc

		// 获取文件内的接口
		apiList := cache.GetFileInfo(v.FileName)
		for _, vApi := range apiList {
			// Vapi, itemData 代表了一个接口
			itemData := item{
				Api: api{
					Domain: domain,
					Type: apiTypeService,
					Name: fmt.Sprintf("%s-%s", descPrefix, vApi.Desc),
					Uri: vApi.Url,
					Protocol: apiProtocolHttp,
					Method: strings.ToUpper(vApi.Method),
					Version: apiDefaultVersion,
					Status: apiStatusNormal,
					Success: "",
					Error: "",
					Remark: "",
					Url: "",
				},
				Config: getItemConfigDefault(),
				Header: header{},
				Response: response{},
				Request: request{},
			}

			// 获取接口内参数
			requestData := request{}
			requestItemList := vApi.Param
			for _, vParam := range requestItemList {
				isMust := paramNo
				if vParam.IsRequired {
					isMust = paramYes
				}
				param := requestItem{
					Param:       vParam.Key,
					Content:     vParam.Name,
					ParamType:   paramTypeString,
					Example: "",
					IsMust: isMust,
					IsRepeat: "",
					IsCross: paramNo,
				}

				requestData.Item = append(requestData.Item, param)
			}
			itemData.Request = requestData

			// 接口信息放入总数据
			dataEol.Item = append(dataEol.Item, itemData)

		}
	}

	//xmlRrefix := "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
	xmlPrefix := ""
	dataEolXml, err := xml.MarshalIndent(dataEol, xmlPrefix, "")
	if err != nil {
		panic(err)
	}

	return string(dataEolXml)
}

func getItemConfigDefault() config {
	return config{
		IsAuth:    paramNo,
		IsAdmin:   paramNo,
		IsCors:    paramYes,
		IsCache:   paramNo,
		CacheType: configCacheTypeFile,
		CacheTime: configDefaultCacheTime,
		Num: configDefaultNum,
		IsEncrypt: paramNo,
	}
}
